from fastapiApp.controllers.user_control import user_controller
from fastapiApp.schemas.user_schemas import UserCreate
from fastapiApp.controllers.api_control import api_controller
from fastapiApp.models.admin import Role_Mo
from fastapiApp.models.admin import Menu_Mo
from fastapiApp.models.admin import Api_Mo
from fastapiApp.models.map import Map_Node_Mo, StationType, AGVStatus, Map_Edge_Mo
from fastapiApp.models.enums import MenuType
from tortoise.expressions import Q

async def init_superuser():
    user = await user_controller.model.exists()
    if not user:
        await user_controller.create_user(
            UserCreate(
                username="admin",
                email="admin@admin.com",
                password="123456",
                is_active=True,
                is_superuser=True,
            )
        )

async def init_apis():
    apis = await api_controller.model.exists()
    if not apis:
        await api_controller.refresh_api()

async def init_roles():
    roles = await Role_Mo.exists()
    if not roles:
        admin_role = await Role_Mo.create(
            name="管理员",
            desc="管理员角色",
        )
        user_role = await Role_Mo.create(
            name="普通用户",
            desc="普通用户角色",
        )

        # 分配所有API给管理员角色
        all_apis = await Api_Mo.all()
        await admin_role.apis.add(*all_apis)
        # 分配所有菜单给管理员和普通用户
        all_menus = await Menu_Mo.all()
        await admin_role.menus.add(*all_menus)
        await user_role.menus.add(*all_menus)

        # 为普通用户分配基本API
        basic_apis = await Api_Mo.filter(Q(method__in=["GET"]) | Q(tags="基础模块"))
        await user_role.apis.add(*basic_apis)

async def init_menus():
    menus = await Menu_Mo.exists()
    if not menus:
        parent_menu = await Menu_Mo.create(
            menu_type=MenuType.CATALOG,
            name="系统管理",
            path="/system",
            order=1,
            parent_id=0,
            icon="carbon:gui-management",
            is_hidden=False,
            component="Layout",
            keepalive=False,
            redirect="/system/user",
        )
        children_menu = [
            Menu_Mo(
                menu_type=MenuType.MENU,
                name="用户管理",
                path="user",
                order=1,
                parent_id=parent_menu.id,
                icon="material-symbols:person-outline-rounded",
                is_hidden=False,
                component="/system/user",
                keepalive=False,
            ),
            Menu_Mo(
                menu_type=MenuType.MENU,
                name="角色管理",
                path="role",
                order=2,
                parent_id=parent_menu.id,
                icon="carbon:user-role",
                is_hidden=False,
                component="/system/role",
                keepalive=False,
            ),
            Menu_Mo(
                menu_type=MenuType.MENU,
                name="菜单管理",
                path="menu",
                order=3,
                parent_id=parent_menu.id,
                icon="material-symbols:list-alt-outline",
                is_hidden=False,
                component="/system/menu",
                keepalive=False,
            ),
            Menu_Mo(
                menu_type=MenuType.MENU,
                name="API管理",
                path="api",
                order=4,
                parent_id=parent_menu.id,
                icon="ant-design:api-outlined",
                is_hidden=False,
                component="/system/api",
                keepalive=False,
            ),
            Menu_Mo(
                menu_type=MenuType.MENU,
                name="部门管理",
                path="dept",
                order=5,
                parent_id=parent_menu.id,
                icon="mingcute:department-line",
                is_hidden=False,
                component="/system/dept",
                keepalive=False,
            ),
            Menu_Mo(
                menu_type=MenuType.MENU,
                name="审计日志",
                path="auditlog",
                order=6,
                parent_id=parent_menu.id,
                icon="ph:clipboard-text-bold",
                is_hidden=False,
                component="/system/auditlog",
                keepalive=False,
            ),
        ]
        await Menu_Mo.bulk_create(children_menu)
        await Menu_Mo.create(
            menu_type=MenuType.MENU,
            name="一级菜单",
            path="/top-menu",
            order=2,
            parent_id=0,
            icon="material-symbols:featured-play-list-outline",
            is_hidden=False,
            component="/top-menu",
            keepalive=False,
            redirect="",
        )

async def init_stations():
    stations = await Map_Node_Mo.exists()
    if not stations:
        # 创建网格节点
        for i in range(1, 16):
            for j in range(1, 9):
                await Map_Node_Mo.create(
                    name=f"N{i}{j}",
                    type=StationType.NODE,
                    status=AGVStatus.UNKNOWN,
                    x=100*i,
                    y=100*j,
                    description=f"节点{i}{j}",
                )

async def init_edges():
    edges = await Map_Edge_Mo.exists()
    
    if not edges:
        # 正向边
        for i in range(1, 16):
            for j in range(1, 8):
                await Map_Edge_Mo.create(
                    weight=1,
                    occupied=0,
                    distance=100,
                    node_from_id=j + (i - 1) * 8,
                    node_to_id=j + (i - 1) * 8 + 1,
                    description=f"边{i}*{j}",
                )

        for i in range(2, 16):
            await Map_Edge_Mo.create(
                weight=1,
                occupied=0,
                distance=100,
                node_from_id = 2 + 8 * (i - 2),
                node_to_id = 2 + 8 * (i - 1),
                description=f"边{2 + 8 * (i - 2)}*{2 + 8 * (i - 1)}",
            )
            await Map_Edge_Mo.create(
                weight=1,
                occupied=0,
                distance=100,
                node_from_id = 7 + 8 * (i - 2),
                node_to_id = 7 + 8 * (i - 1),
                description=f"边{7 + 8 * (i - 2)}*{7 + 8 * (i - 1)}",
            )
            
        # 反向边
        for i in range(1, 16):
            for j in range(1, 8):
                await Map_Edge_Mo.create(
                    weight=1,
                    occupied=0,
                    distance=100,
                    node_from_id=j + (i - 1) * 8 + 1,
                    node_to_id=j + (i - 1) * 8,
                    description=f"边{i}*{j}",
                )
        for i in range(2, 16):
            await Map_Edge_Mo.create(
                weight=1,
                occupied=0,
                distance=100,
                node_from_id = 2 + 8 * (i - 1),
                node_to_id = 2 + 8 * (i - 2),
                description=f"边{2 + 8 * (i - 1)}*{2 + 8 * (i - 2)}",
            )
        for i in range(2, 16):
            await Map_Edge_Mo.create(
                weight=1,
                occupied=0,
                distance=100,
                node_from_id = 7 + 8 * (i - 1),
                node_to_id = 7 + 8 * (i - 2),
                description=f"边{7 + 8 * (i - 1)}*{7 + 8 * (i - 2)}",
            )

async def init_data():
    # await init_db()
    await init_superuser()
    await init_apis()
    await init_roles()
    await init_menus()
    await init_stations()
    await init_edges()
